/**
 * 
 */
package org.vsg.stock.basic.service.volfigure.iecrease;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.vsg.common.biz.exception.ServiceException;
import org.vsg.stock.basic.domain.VolFigureDetails;
import org.vsg.stock.basic.domain.VolFigureKlineDaily;
import org.vsg.stock.basic.domain.VolFigureKlineDailyPK;
import org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor;
import org.vsg.stock.basic.service.volfigure.CommonParameter;
import org.vsg.stock.core.domain.StockDailyKLine;
import org.vsg.stock.core.indicator.kline.ZigIndicatorResultItem;

/**
 * 梯量柱模式"increase-3c-1a3"
 *  
 *  
 * @author Bill Vison
 *
 */
public class Iecrease3c1a3Processor implements VolFigureKlineDailyProcessor,ApplicationContextAware {

	static private DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

	DecimalFormat nf = new DecimalFormat("##0.000");	
	
	private Set<String> dailyKeys = new HashSet<String>();	

	
	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#processDailyData(java.util.List)
	 */
	@Override
	public List<VolFigureKlineDaily> processDailyData(
			List<StockDailyKLine> stkDailyKLineList) {

		List<VolFigureKlineDaily> klineDailyList = new Vector<VolFigureKlineDaily>();		
		
		StockDailyKLine startLeveKline = null;

		for (int i = 0 ; i < stkDailyKLineList.size() ; i++) {

			int offsetResult = validateMatch(stkDailyKLineList , i );
			// --- mark offset result ---
			if (offsetResult == 0) {
				continue;
			}
			
			// --- set the limit set ---
			startLeveKline = stkDailyKLineList.get(i);
			
			// --- main program get the date ---
			try {
				//System.out.println(startLeveKline.getId().getStockCode() + " , " + df.format( startLeveKline.getDate() ));				
				
				if ( offsetResult != 2) {
					throw new ServiceException("offset result not equal 2");
				}
				
				StockDailyKLine startKLine = stkDailyKLineList.get( i );
				StockDailyKLine endKLine = stkDailyKLineList.get( i+offsetResult );		
				
				String indexLine = startLeveKline.getId().getStockCode()+","+detail.getCode()+","+df.format( startKLine.getDate() );
				//System.out.println(indexLine);
				
				// --- key format example "SH00001,XXXX,2010-01-10"
				if (this.dailyKeys.contains( indexLine) ) {
					continue;
				}
				
				// --- mark the date ---
				VolFigureKlineDailyPK idPk = new VolFigureKlineDailyPK();
				idPk.setCodeVolFigureDetails( this.detail.getCode() );
				idPk.setStockCode( startLeveKline.getId().getStockCode() );
				idPk.setStockStartDate( startKLine.getDate() );
				
				// --- gen new data object ---
				VolFigureKlineDaily dailyInst = new VolFigureKlineDaily();
				dailyInst.setId( idPk );
				dailyInst.setStockDateEnd( endKLine.getDate());			

				klineDailyList.add( dailyInst );				
				
			} catch (ServiceException e) {

			} finally {
				
				// --- update offset ---
				i = i+offsetResult;
				
			}


		}
		
		return klineDailyList;
	}


	private int validateMatch(List<StockDailyKLine> stkDailyKLineList , int index ) {
		
		StockDailyKLine startDailyKLine = stkDailyKLineList.get(index);
		
		// --- yield rate must greater than 0 ----
		if ( startDailyKLine.getYieldRate() < 0 ) {
			return 0;
		}
		
		long startDailyKLineVol = startDailyKLine.getVol();
		long tmpLastVol = startDailyKLineVol;
		int offset = 0;

		
		while (true) {
			
			offset+=1;
			int tmpIndex = index+ offset;
			
			try {

				StockDailyKLine tmpKLine = stkDailyKLineList.get(tmpIndex);
				
				// --- 非阴和偏移不够3天
				if (tmpKLine.getYieldRate() < 0
					|| tmpLastVol > tmpKLine.getVol()
				) {
					break;
				}
				
				tmpLastVol = tmpKLine.getVol();
				
			} catch (java.lang.IndexOutOfBoundsException iobe) {
				
				break;
				
			}
			
		}

		// ---- add vol limit condition ---
		if ( offset == 3) {
		
			int currIndex = 0;
			for (int i = 1 ; i < offset ; i++) {
				currIndex = index + i;
				// --- 当天 ---
				long currentDailyVol = stkDailyKLineList.get(currIndex).getVol();			
				// --- 上一天 ---
				long preDailyVol = stkDailyKLineList.get(currIndex - 1).getVol();
				
				// --- 出现倍量柱 ---
				if ( currentDailyVol * CommonParameter.SEPRATE_RATE < preDailyVol) {
					return 0;
				}
				
			}
			
		}
		
		if ( offset < 3) {
			offset = 0;
		} else {
			offset = offset - 1;
		}
		
		
		// ---- limit the offset is 2 ---


		return offset;
	}
	


	
	private List<ZigIndicatorResultItem> crests;

	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#setCrestsInCycle(java.util.List)
	 */
	@Override
	public void setCrestsInCycle(List<ZigIndicatorResultItem> crests) {
		this.crests = crests;

	}

	@Override
	public void setExistedVolFigureKineDaily(
			List<VolFigureKlineDaily> volFigureKlineDailyList) {
		// --- get the daily ---
		VolFigureKlineDailyPK id = null;
		for (VolFigureKlineDaily daily : volFigureKlineDailyList) {
			id = daily.getId();
			String keyLine = id.getStockCode()+ "," + id.getCodeVolFigureDetails()+"," + df.format( id.getStockStartDate() );
			dailyKeys.add( keyLine );
		}
		
	}

	private VolFigureDetails detail;	
	
	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#setCurrentVolFigureDetails(org.vsg.stock.basic.domain.VolFigureDetails)
	 */
	@Override
	public void setCurrentVolFigureDetails(VolFigureDetails detail) {
		this.detail = detail;

	}

	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#setTroughsInCycle(java.util.List)
	 */
	@Override
	public void setTroughsInCycle(List<ZigIndicatorResultItem> troughs) {
		// TODO Auto-generated method stub

	}

}
